package com.kk.BlockingQueue接口的使用;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

class BlockingQueueTest {

    /**
     * ArrayBlockingQueue ：基于数组实现的BlockingQueue队列。
     * LinkedBlockingQueue：基于链表实现的BlockingQueue队列。
     * PriorityBlockingQueue：它并不是保准的阻塞队列，该队列调用remove（）、poll（）、take（）等方法提取出元素时，并不是取出队列中存在时间最长的元素，而是队列中最小的元素。
     * 它判断元素的大小即可根据元素（实现Comparable接口）的本身大小来自然排序，也可使用Comparator进行定制排序。
     * SynchronousQueue：同步队列。对该队列的存、取操作必须交替进行。
     * DelayQueue：它是一个特殊的BlockingQueue，底层基于PriorityBlockingQueue实现，不过，DelayQueue要求集合元素都实现Delay接口（该接口里只有一个long getDelay（）方法），
     * DelayQueue根据集合元素的getDalay（）方法的返回值进行排序。
     *
     * @param args
     * @throws Exception
     */
    public static void main(String[] args) throws Exception {
        //创建一个容量为1的BlockingQueue
        BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(1);
        //启动3个生产者线程
        new Producer(blockingQueue).start();
        new Producer(blockingQueue).start();
        new Producer(blockingQueue).start();
        //启动一个消费者线程
        new Consumer(blockingQueue).start();

    }
}

class Producer extends Thread {
    private final BlockingQueue<String> blockingQueue;

    public Producer(BlockingQueue<String> blockingQueue) {
        this.blockingQueue = blockingQueue;

    }

    @Override
    public synchronized void run() {
        String[] str = new String[]{
                "java",
                "struts",
                "Spring"
        };
        for (int i = 0; i < Integer.MAX_VALUE; i++) {
            System.out.println(getName() + "生产者生产元素...");
            try {
                //尝试放入元素，如果队列已满，则线程被阻塞
                blockingQueue.put(str[i % 3]);
            } catch (Exception e) {
                System.out.println(e);
            }
            System.out.println(getName() + "生产完成：" + blockingQueue);
        }

    }
}

class Consumer extends Thread {
    private final BlockingQueue<String> blockingQueue;

    public Consumer(BlockingQueue<String> blockingQueue) {
        this.blockingQueue = blockingQueue;
    }

    @Override
    public synchronized void run() {

        while (true) {
            System.out.println(getName() + "消费者消费元素！");
            try {
                sleep(1000);
                //尝试取出元素，如果队列已空，则线程被阻塞
                blockingQueue.take();
            } catch (Exception e) {
                System.out.println(e);
            }
            System.out.println(getName() + "消费完成, 看看盘子：" + blockingQueue);
        }

    }
}
